﻿namespace WebinatorTest.IntegrationTests
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using NUnit.Framework;
    using Webinator;
    using Webinator.Enums;
    using Webinator.Toolboxes;

    using WebinatorTest.BaseTests;

    [TestFixture]
    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed. Suppression is OK here.")]
    public class DomTests : WebDriverBaseTest
    {
        /// <summary>
        /// Runs before each test
        /// </summary>
        [SetUp]
        public void SetupWebDriver()
        {
            Web.GoToUrl("http://localhost:8181/TestFiles/HighlighterTest.html");
        }

        [Test]
        public void TestXpath()
        {
            Assert.AreEqual("//input[@id='id'][@type='text']", Web.Dom.Textbox(ByAttribute.Id("id")).Xpath);
            Assert.AreEqual("//body//input[text()='something'][@type='text']", Web.Dom.Body.Textbox(ByAttribute.Text("something")).Xpath);
            Assert.AreEqual("//input[@id='id' or @name='name'][@type='text']", Web.Dom.Textbox(ByAttribute.Id("id").OrName("name")).Xpath);
            Assert.AreEqual("(//table)[1]", Web.Dom.Tables.First().Xpath);
            Assert.AreEqual("(//table)[1]//td//div", Web.Dom.Tables.First().TableCells.Divs.Xpath);
            Assert.AreEqual("(//table)[1]//tbody//tr//td//div", Web.Dom.Tables.Last().TableBodies.TableRows.TableCells.Divs.Xpath);
            Assert.AreEqual("//table//tbody//tr//td//div", Web.Dom.Tables.TableBodies.TableRows.TableCells.Divs.Xpath);
            Assert.AreEqual("(//table//tbody//tr//td//div)[1]", Web.Dom.Tables.TableBodies.TableRows.TableCells.Divs.First().Xpath);
        }

        [Test]
        public void TestIterator()
        {
            var cells = Web.Dom.TableCells.Divs;
            Assert.AreEqual(25, cells.Count());
        }

        [Test]
        public void TestGetValue()
        {
            var textbox = Web.Dom.Textboxes.First();

            textbox.SendKeys("hello world");
            Assert.AreEqual("hello world", textbox.Value);
        }

        [Test]
        public void TestPositioning()
        {
            Assert.AreEqual(25, Web.Dom.Tables.First().TableCells.Divs.Count());
            Assert.AreEqual(25, Web.Dom.Tables.Last().TableBodies.TableRows.TableCells.Divs.Count());
        }

        [Test]
        public void TestIndexer()
        {
            Assert.AreEqual("(//table)[1]", Web.Dom.Tables[0].Xpath);
            Assert.AreEqual("((//table)[1]//td)[6]", Web.Dom.Tables[0].TableCells[5].Xpath);
        }

        [Test]
        public void TestForEach()
        {
            foreach (var td in Web.Dom.TableCells)
            {
                Console.WriteLine(td.Text);
            }

            Web.Dom.Checkboxes.ForEach(cb => cb.SelectCheckbox(true));
            Web.Dom.Checkboxes.ForEach(cb => Assert.IsTrue(cb.IsSelected));
        }

        [Test]
        public void TestLinq()
        {
            var tds = Web.Dom.TableCells.Where(td => td.Class == "linq");

            Assert.AreEqual(6, tds.Count());
        }

        [Test]
        public void TestGetLocator()
        {
            Assert.AreEqual("(//table)[1]//tr", Web.Dom.Tables.First().TableRows.Locator.Value);
            Assert.AreEqual(Use.All, Web.Dom.Tables.First().TableRows.Locator.Use);
            Assert.AreEqual("((//table)[1]//td)[25]", Web.Dom.Tables.First().TableCells.Last().Locator.Value);
            Assert.AreEqual(Use.One, Web.Dom.Tables.First().TableCells.Last().Locator.Use);
        }

        [Test]
        public void TestHtmlDom()
        {
            Assert.AreEqual("//input[@id='id'][@type='text']", XPathToolbox.GetDom(Web.PageSource()).Textbox(ByAttribute.Id("id")).Xpath);
            Assert.AreEqual("//body//input[text()='something'][@type='text']", XPathToolbox.GetDom(Web.PageSource()).Body.Textbox(ByAttribute.Text("something")).Xpath);
            Assert.AreEqual("//input[@id='id' or @name='name'][@type='text']", XPathToolbox.GetDom(Web.PageSource()).Textbox(ByAttribute.Id("id").OrName("name")).Xpath);
            Assert.AreEqual("(//table)[1]", XPathToolbox.GetDom(Web.PageSource()).Tables.First().Xpath);
            Assert.AreEqual("(//table)[1]//td//div", XPathToolbox.GetDom(Web.PageSource()).Tables.First().TableCells.Divs.Xpath);
            Assert.AreEqual("(//table)[1]//tbody//tr//td//div", XPathToolbox.GetDom(Web.PageSource()).Tables.Last().TableBodies.TableRows.TableCells.Divs.Xpath);
            Assert.AreEqual("//table//tbody//tr//td//div", XPathToolbox.GetDom(Web.PageSource()).Tables.TableBodies.TableRows.TableCells.Divs.Xpath);
            Assert.AreEqual("(//table//tbody//tr//td//div)[1]", XPathToolbox.GetDom(Web.PageSource()).Tables.TableBodies.TableRows.TableCells.Divs.First().Xpath);
        }

        [Test]
        public void TestThrowElementInteraction()
        {
            Assert.Throws<NullReferenceException>(
                () => XPathToolbox.GetDom(Web.PageSource()).Checkboxes.ForEach(cb => cb.SelectCheckbox(true)));
        }
    }
}
